
#ifndef BOOK_MANAGEMENT_GUARD__H 
#define BOOK_MANAGEMENT_GUARD__H

#include <stdio.h>

/*You can extend the structs (Book and BookList) defined in this head file;
  However, you may not change the function prototypes. 
  You are also free to add additional head files and data structures as needed. 
*/


typedef struct _Book {
	    unsigned int id; //Book ID
		char *title; //book title
		char *authors; //comma separated list of authors
		unsigned int year; // year of publication
		unsigned int copies; //number of copies the library has
		unsigned int lend; //number of books readers lent
		struct _Book *next; //pointer to the next book element
}Book;

typedef struct _BookList {
	 Book* list; // pointer to a list of struct Book.
	 unsigned int length; // number of elements in the (Book*) List 
}BookList;

typedef struct _Student {
	unsigned int id; // student ID
	char* name; // student Name
	char* username; // username when logging in
	char* password; // password when logging in and the length is larger than 5
	unsigned int borrow; // number of books the student borrowed
    struct _Student* next; //pointer to the next student element
}Student;

typedef struct _StudentList{
    Student* list; // pointer to a list of struct Student.
    unsigned int length; // number of elements in the (Student*) List
}StudentList;

typedef struct _BorrowInformation {
	unsigned int stuID; // Student ID who borrow books
	unsigned int bookID; // Book ID which was borrowed by the student whose ID is stuID
	struct _BorrowInformation* next; // pointer to the next BorrowInformation element
}BorrowInformation;


extern char* librarianUsername; // The librarian's username when logging in
extern char* librarianPassword; // The librarian's password when logging in, and the length must be larger than 5


//saves the database of books in the specified file
//returns 0 if books were stored correctly, or an error code otherwise
int store_books(FILE *file, Book* books, BookList* theBook);

//saves the database of readers in the specified file
//returns 0 if readers were stored correctly, or an error code otherwise
int store_readers(FILE* file, Student* students, StudentList* theStudent);

// save the database of borrowing information, from one student ID to one book ID
// returns 0 if borrowing information was stored correctly, or an error code otherwise
int store_borrowInformation(FILE* file, BorrowInformation* borrows);

//loads the database of books from the specified file
//the file must have been generated by a previous call to store_books()
//returns 0 if books were loaded correctly, or an error code otherwise
int load_books(FILE *file, Book* books, BookList* theBook);

//loads the database of students from the specified file
//the file has already been in the bin directory
//returns 0 if students were loaded correctly, or an error code otherwise
int load_students(FILE* file, Student* students, StudentList* theStudent);

int load_borrowInformation(FILE* file, BorrowInformation* borrows);

//adds a book to the ones available to the library
//returns 0 if the book could be added, or an error code otherwise
int add_book(Book book);

//removes a book from the library
//returns 0 if the book could be successfully removed, or an error code otherwise.
int remove_book(Book book);

//finds books with a given title.
//returns a BookList structure, where the field "list" is a list of books, or null if no book with the 
//provided title can be found. The length of the list is also recorded in the returned structure, with 0 in case
//list is the NULL pointer.
BookList find_book_by_title (Book* books, BookList* theBook, const char *title);

//finds books with the given authors.
//returns a Booklist structure, where the field "list" is a newly allocated list of books, or null if no book with the 
//provided title can be found. The length of the list is also recorded in the returned structure, with 0 in case
//list is the NULL pointer.
BookList find_book_by_author (Book* books, BookList* theBook, const char *author);

//finds books published in the given year.
//returns a Booklist structure, where the field "list" is a list of books, or null if no book with the 
//provided title can be found. The length of the list is also recorded in the returned structure, with 0 in case
//list is the NULL pointer.
BookList find_book_by_year (Book* books, BookList* theBook, unsigned int year);

//finds books published in the given id.
//returns a Booklist structure, where the field "list" is a list of books, or null if no book with the 
//provided title can be found. The length of the list is also recorded in the returned structure, with 0 in case
//list is the NULL pointer.
BookList find_book_by_id (Book* books, BookList* theBook, unsigned int id);

//finds books published in the given number of copies.
//returns a Booklist structure, where the field "list" is a list of books, or null if no book with the 
//provided title can be found. The length of the list is also recorded in the returned structure, with 0 in case
//list is the NULL pointer.
BookList find_book_by_copies (Book* books, BookList* theBook, unsigned int copies);

//finds students in the given id.
//returns nothing
void searchReadersID(Student* students, StudentList* theStudent, unsigned int id);

//finds students in the given name.
//returns nothing
void searchReadersName(Student* students, StudentList* theStudent, char* name);


#endif
